package com.ken.common.event.apply.utils;

import com.ken.common.event.apply.delay.DelayTime;
import com.ken.common.event.framework.message.EventMessage;
import com.ken.common.event.framework.message.factory.MsgFactory;
import com.ken.common.event.framework.processor.SendMsgPostProcessor;
import com.ken.common.event.framework.producer.ProducerStandard;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * 事件发布工具类
 */
@Slf4j
public class EventUtils {

    @Autowired
    private ProducerStandard producerStandard;

    @Autowired
    private MsgFactory msgFactory;

    @Autowired(required = false)
    private List<SendMsgPostProcessor> sendMsgPostProcessors;

    /**
     * 发送指定消息 - 可选择是否持久
     * @param eventType
     * @param msg
     * @param durable
     * @param <T>
     */
    public <T> void sendMsg(String eventType, T msg, boolean durable){
        log.debug("[Send-Msg] - 发送实时消息 事件类型 - {} 消息内容 - {}", eventType, msg);
        EventMessage<T> eventMessage = msgFactory.createMessage(msg);
        if (processors(eventType, eventMessage)) {
            producerStandard.sendEvent(eventType, eventMessage, durable);
        }
    }

    /**
     * 发送延迟消息
     * @param <T>
     */
    public <T> void sendDelayMsg(String eventType,T msg, boolean durable, DelayTime delayTime){
        log.debug("[Send-Msg] - 发送延迟消息 事件类型 - {} 消息内容 - {} 延迟时间 - {}", eventType, msg, delayTime.getName());
        EventMessage<T> eventMessage = msgFactory.createMessage(msg);
        if (processors(eventType, eventMessage)) {
            producerStandard.sendDelayEvent(eventType, eventMessage, durable, delayTime);
        }
    }

    /**
     * 进行消息发送前处理
     * @return
     */
    private boolean processors(String eventType, EventMessage eventMessage){
        log.debug("[Send-Msg] - 执行消息发送前的Processor - {}", sendMsgPostProcessors);
        if (!CollectionUtils.isEmpty(sendMsgPostProcessors))
            A:for (SendMsgPostProcessor sendMsgPostProcessor : sendMsgPostProcessors) {
                if (!sendMsgPostProcessor.isSupport(eventType, eventMessage))
                    continue A;
                if (!sendMsgPostProcessor.beforeProcessor(eventType, eventMessage))
                    return false;
            }
        return true;
    }
}
